#ifndef INICONFIG_H
#define INICONFIG_H

#include <QMutex>
#include <QObject>
#include <QSettings>
#include <QString>
#include <QVariant>

/**
 * @brief 简单的全局INI配置管理类
 *
 * 提供线程安全的INI配置文件读写功能
 * 使用单例模式，支持自动保存
 */
class IniConfig : public QObject
{
    Q_OBJECT

public:
    /**
     * @brief 获取配置管理器单例
     * @return 配置管理器实例
     */
    static IniConfig* instance();

    /**
     * @brief 设置配置文件路径
     * @param filePath INI配置文件路径
     */
    void setConfigFile(const QString& filePath);

    /**
     * @brief 获取当前配置文件路径
     * @return 配置文件路径
     */
    QString configFile() const;

    /**
     * @brief 读取配置值
     * @param key 配置键名（支持 "section/key" 格式）
     * @param defaultValue 默认值
     * @return 配置值
     */
    QVariant value(const QString& key, const QVariant& defaultValue = QVariant()) const;

    /**
     * @brief 设置配置值
     * @param key 配置键名（支持 "section/key" 格式）
     * @param value 配置值
     */
    void setValue(const QString& key, const QVariant& value);

    /**
     * @brief 读取字符串值
     * @param key 配置键名
     * @param defaultValue 默认值
     * @return 字符串值
     */
    QString getString(const QString& key, const QString& defaultValue = QString()) const;

    /**
     * @brief 读取整数值
     * @param key 配置键名
     * @param defaultValue 默认值
     * @return 整数值
     */
    int getInt(const QString& key, int defaultValue = 0) const;

    /**
     * @brief 读取布尔值
     * @param key 配置键名
     * @param defaultValue 默认值
     * @return 布尔值
     */
    bool getBool(const QString& key, bool defaultValue = false) const;

    /**
     * @brief 读取浮点数值
     * @param key 配置键名
     * @param defaultValue 默认值
     * @return 浮点数值
     */
    double getDouble(const QString& key, double defaultValue = 0.0) const;

    /**
     * @brief 设置字符串值
     * @param key 配置键名
     * @param value 字符串值
     */
    void setString(const QString& key, const QString& value);

    /**
     * @brief 设置整数值
     * @param key 配置键名
     * @param value 整数值
     */
    void setInt(const QString& key, int value);

    /**
     * @brief 设置布尔值
     * @param key 配置键名
     * @param value 布尔值
     */
    void setBool(const QString& key, bool value);

    /**
     * @brief 设置浮点数值
     * @param key 配置键名
     * @param value 浮点数值
     */
    void setDouble(const QString& key, double value);

    /**
     * @brief 检查配置键是否存在
     * @param key 配置键名
     * @return 存在返回true，否则返回false
     */
    bool contains(const QString& key) const;

    /**
     * @brief 移除配置键
     * @param key 配置键名
     */
    void remove(const QString& key);

    /**
     * @brief 获取所有配置组
     * @return 配置组列表
     */
    QStringList childGroups() const;

    /**
     * @brief 获取指定组下的所有键
     * @param group 配置组名
     * @return 键名列表
     */
    QStringList childKeys(const QString& group = QString()) const;

    /**
     * @brief 同步配置到文件
     */
    void sync();

    /**
     * @brief 清空所有配置
     */
    void clear();

signals:
    /**
     * @brief 配置值变更信号
     * @param key 变更的键名
     * @param value 新值
     */
    void valueChanged(const QString& key, const QVariant& value);

private:
    explicit IniConfig(QObject* parent = nullptr);
    ~IniConfig();

    // 禁止拷贝
    IniConfig(const IniConfig&) = delete;
    IniConfig& operator=(const IniConfig&) = delete;

    // 单例实例
    static IniConfig* m_instance;
    static QMutex m_mutex;

    // QSettings实例
    QSettings* m_settings;

    // 配置文件路径
    QString m_configFilePath;

    // 线程安全锁
    mutable QMutex m_settingsMutex;
};

// 便捷的全局函数
namespace IniConfigGlobal {
/**
 * @brief 读取配置值
 */
inline QVariant getValue(const QString& key, const QVariant& defaultValue = QVariant())
{
    return IniConfig::instance()->value(key, defaultValue);
}

/**
 * @brief 设置配置值
 */
inline void setValue(const QString& key, const QVariant& value)
{
    IniConfig::instance()->setValue(key, value);
}

/**
 * @brief 读取字符串值
 */
inline QString getString(const QString& key, const QString& defaultValue = QString())
{
    return IniConfig::instance()->getString(key, defaultValue);
}

/**
 * @brief 读取整数值
 */
inline int getInt(const QString& key, int defaultValue = 0)
{
    return IniConfig::instance()->getInt(key, defaultValue);
}

/**
 * @brief 读取布尔值
 */
inline bool getBool(const QString& key, bool defaultValue = false)
{
    return IniConfig::instance()->getBool(key, defaultValue);
}

/**
 * @brief 读取浮点数值
 */
inline double getDouble(const QString& key, double defaultValue = 0.0)
{
    return IniConfig::instance()->getDouble(key, defaultValue);
}

/**
 * @brief 设置字符串值
 */
inline void setString(const QString& key, const QString& value)
{
    IniConfig::instance()->setString(key, value);
}

/**
 * @brief 设置整数值
 */
inline void setInt(const QString& key, int value) { IniConfig::instance()->setInt(key, value); }

/**
 * @brief 设置布尔值
 */
inline void setBool(const QString& key, bool value) { IniConfig::instance()->setBool(key, value); }

/**
 * @brief 设置浮点数值
 */
inline void setDouble(const QString& key, double value)
{
    IniConfig::instance()->setDouble(key, value);
}

/**
 * @brief 检查配置键是否存在
 */
inline bool hasKey(const QString& key) { return IniConfig::instance()->contains(key); }

/**
 * @brief 同步配置到文件
 */
inline void sync() { IniConfig::instance()->sync(); }
}  // namespace IniConfigGlobal

#endif  // INICONFIG_H